const WeatherCache = require('../models/WeatherCache');
const axios = require('axios');

const getHistoricalWeather = async (req, res) => {
  const { location } = req.params; // Get location from route parameters
  const { date } = req.query; // Get date from query parameters

  try {
    if (!location || !date) {
      return res.status(400).json({ message: 'Location and date are required.' });
    }

    const AMAP_API_KEY = process.env.AMAP_API_KEY; 

    // Geocoding: Get adcode from location name using Gaode Geocoding API
    const geoResponse = await axios.get(`https://restapi.amap.com/v3/geocode/geo?address=${location}&key=${AMAP_API_KEY}`);
    if (!geoResponse.data || geoResponse.data.status !== '1' || geoResponse.data.geocodes.length === 0) {
      return res.status(404).json({ message: 'Location not found or geocoding failed.' });
    }
    const adcode = geoResponse.data.geocodes[0].adcode; // Gaode uses adcode for weather queries
    const city_id = adcode; // Use adcode as city_id for caching

    // First, try to fetch from cache
    let weatherData = await WeatherCache.findOne({
      where: {
        city_id: city_id,
        date: new Date(date) // Store/query as Date object
      }
    });

    if (weatherData) {
      return res.status(200).json(weatherData);
    }

    // If not in cache, fetch from Gaode Weather API (Forecast)
    // Gaode's public API doesn't provide true historical weather. 
    // We will fetch forecast data and try to match the date.
    const weatherResponse = await axios.get(`https://restapi.amap.com/v3/weather/weatherInfo?city=${adcode}&extensions=all&key=${AMAP_API_KEY}`);
    
    if (!weatherResponse.data || weatherResponse.data.status !== '1' || weatherResponse.data.forecasts.length === 0) {
      return res.status(404).json({ message: 'Weather data not available for this location.' });
    }

    const forecasts = weatherResponse.data.forecasts[0].casts;
    const targetDate = new Date(date);
    let dailyForecast = null;

    // Find the forecast for the requested date
    for (const forecast of forecasts) {
      if (new Date(forecast.date).toDateString() === targetDate.toDateString()) {
        dailyForecast = forecast;
        break;
      }
    }

    if (!dailyForecast) {
      return res.status(404).json({ message: 'No forecast data available for the specified date within the available range.' });
    }

    // Extract and format data for storage
    const newWeatherData = {
      city_id: city_id,
      date: new Date(date),
      temperature: dailyForecast.daytemp, // Using day temperature as an example
      humidity: 0, // Gaode forecast API doesn't provide humidity directly
      wind_speed: dailyForecast.daypower, // Using day wind power as an example
      air_quality: dailyForecast.dayweather, // Using day weather description as a placeholder for air quality
      precipitation: 0 // Gaode forecast API doesn't provide precipitation directly
    };

    // Store in cache
    weatherData = await WeatherCache.create(newWeatherData);
    res.status(200).json(weatherData);

  } catch (error) {
    console.error('Error fetching historical weather:', error.response?.data || error.message);
    res.status(500).json({ message: 'Server error' });
  }
};

module.exports = { getHistoricalWeather }; 